. $TONE_ROOT/lib/disk.sh

# - fs
# - ioengine
# - direct
# - test_size
# - rw
# - bs
# - iodepth
# - nr_task

check_test_size()
{
    local disk_name=$1
    local test_size=$2
    # limit test_size under available disk size
    [[ $(size_cn_bytes $test_size) -gt $(lsblk -b -P -o 'SIZE' ${disk_name} | head -1 | egrep -o '[0-9]+') ]] && return 1 || return 0
}

get_test_disk()
{
    local type_disk=
    local type_part=
    local test_size=$1

    for disk_name in $(lsblk -b -P -o 'NAME' | awk -F"=" '{print $2}' | sed 's/\"//g' | sort) ;do
        if $(lsblk -b -P -o 'TYPE' /dev/${disk_name} | grep -q 'disk');then
            type_disk="$type_disk /dev/${disk_name}"    
        elif $(lsblk -b -P -o 'TYPE' /dev/${disk_name} | grep -q 'part');then
            type_part="$type_part /dev/${disk_name}"    
        fi
    done

    local usable_disks=${type_disk}
    for disk in $(echo ${type_disk} | xargs -n 1);do
        if ! $(check_test_size ${disk} ${test_size}); then
            usable_disks=$(echo ${usable_disks} | sed "s|$disk||" )
            echo "${disk} less than testsize"
        fi
    done
    
    local unusable_parts=
    for part in $(echo ${type_part} | xargs -n 1);do 
        if ! $(lsblk -b -P -o 'MOUNTPOINT' ${part} | grep -q '\"\"')  ;then
            unusable_parts="${unusable_parts} ${part}"
            echo "${part} already mounted"
        fi
    done

    for usable_disk in $(echo ${usable_disks} | xargs -n 1); do 
        if ! $(echo ${unusable_parts} | grep -q ${usable_disk}); then
            echo "${usable_disk} will be used for fio test"
            test_disk=${usable_disk}
            return 0
        fi
    done
}

mkfs_and_mount()
{
    local test_disk=$1
    local fs=$2
    
    logger wipefs -a -f ${test_disk}
    logger partprobe ${test_disk}
    logger parted -s ${test_disk} mklabel gpt mkpart primary 0% 100%
    
    sleep 3
    test_disk="/dev/$(lsblk -b -P -o 'NAME','TYPE' ${test_disk} | grep 'part' | awk -F"[= ]" '{print $2}' |sed 's/"//g')"
    case ${fs} in
        xfs)
            logger mkfs -t xfs -f -L tone ${test_disk}
            sleep 3
        ;; 
        ext4)
            logger mkfs -t ext4 -E lazy_itable_init=0,lazy_journal_init=0 -L tone -q -F ${test_disk}
            sleep 3
        ;; 
    esac

    mnt=/fs/$(basename ${test_disk})
    logger mkdir -p ${mnt}
    logger mount -t ${fs} ${test_disk} ${mnt}
}

check_testdisk()
{
    local test_disk=$1
    local test_size=$2
    check_test_size ${test_disk} ${test_size} || exit 1
    if $(lsblk -b -P -o 'MOUNTPOINT' ${test_disk} | grep -q '"\/"');then
        echo "${test_disk} is Linux’s root(/), test abort"
        exit 1
    fi
    test_disk="/dev/$(lsblk -b -P -o 'NAME','TYPE' ${test_disk} | grep 'part' | awk -F"[= ]" '{print $2}' |sed 's/"//g')"
    mount | grep -q ${test_disk} && umount ${test_disk}
}

test_disk=
mnt=
init_task=

setup()
{
    if [ -z "$TEST_DISK" ]; then
        get_test_disk ${test_size}
    else
        if $(echo $TEST_DISK | grep -q '/dev');then
            test_disk="${TEST_DISK}"
        else
            test_disk="/dev/${TEST_DISK}"
        fi
        check_testdisk ${test_disk} ${test_size}
    fi
    
    [ -z "$test_disk" ] && echo "No disk for fio test" && exit 1
    [ -z "$fs" ] || mkfs_and_mount ${test_disk} ${fs}
    [ -z "$mnt" ] && task_type="filename=${test_disk}" || task_type="directory=${mnt}"
    [ -z "$iodepth" ] || iodepth_ops="iodepth=$iodepth"
    test_size=$(size_cn_bytes $test_size)
    size=$((test_size / nr_task))
    
    init_task="\
[global]
ioengine=$ioengine
size=$size
direct=$direct
bs=$bs
$iodepth_ops
time_based
ramp_time=${RANM_TIME:=30}
runtime=${RUNTIME:=300}
[tone_task]
$task_type
numjobs=$nr_task
rw=$rw
"

}

run()
{
    local task_path=$TONE_CURRENT_RESULT_DIR/fio.task
    local task_output=$TONE_CURRENT_RESULT_DIR/fio.output
    export PATH="$PATH:$TONE_BM_RUN_DIR/bin"

    echo -n "$init_task" > ${task_path}
    logger "$NUMACTL" fio --output-format=json "$task_path" --output="$task_output"
}

teardown()
{
    local test_dir=$(cat $TONE_CURRENT_RESULT_DIR/fio.task | grep directory | awk -F'=' '{print $NF}')
    if ! [ -z "$test_dir" ];then
        logger sync
        logger umount -l -f $test_dir
        logger rm -rf $test_dir
    fi
    exit 0
}

parse()
{
    python $TONE_BM_SUITE_DIR/parse.py
}
